package com.welink.cmp.statemachine.actions;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.welink.base.statemachine.Action;
import com.welink.cmp.dao.common.OperationLogService;
import com.welink.cmp.dao.metadata.FirewallDaoService;
import com.welink.cmp.dao.metadata.RouterDaoService;
import com.welink.cmp.dao.metadata.SwitchDaoService;
import com.welink.cmp.dao.metadata.dataobject.FirewallDO;
import com.welink.cmp.dao.metadata.dataobject.RouterDO;
import com.welink.cmp.dao.metadata.dataobject.SwitchDO;
import com.welink.cmp.domain.metadata.enums.ResourceTypeEnum;
import com.welink.cmp.statemachine.context.CommonCtx;
import com.welink.cmp.statemachine.machine.CommonEvent;
import com.welink.cmp.statemachine.machine.CommonState;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @author yanwei li create  2024-06-11 14:46
 */
@Service
@Slf4j
public class CommonActions {

    @Resource
    private OperationLogService logService;
    @Resource
    private FirewallDaoService firewallDaoService;
    @Resource
    private SwitchDaoService switchDaoService;
    @Resource
    private RouterDaoService routerDaoService;

    @Transactional(rollbackFor = Exception.class)
    public Action<CommonState, CommonEvent, CommonCtx> doAction() {
        return (from, to, event, ctx)->{
            final int beforeStateCode = from.getCode();
            final int afterStateCode = to.getCode();
            final ResourceTypeEnum typeEnum = ctx.getTypeEnum();

            switch (typeEnum){
                case FIREWALL:
                    fwAction(beforeStateCode,afterStateCode,event,ctx);
                    break;
                case SWITCH:
                    switchAction(beforeStateCode,afterStateCode,event,ctx);
                    break;
                case ROUTER:
                    routerAction(beforeStateCode,afterStateCode,event,ctx);
                    break;
                default:
                    log.info("未知资源");
            }
        };
    }


    public void fwAction(Integer beforeStateCode,Integer afterStateCode,CommonEvent event,CommonCtx ctx){
        LambdaUpdateWrapper<FirewallDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(FirewallDO::getStatus,afterStateCode);
        if (ctx.getLaunchedTime() != null){
            updateWrapper.set(FirewallDO::getLaunchedTime,ctx.getLaunchedTime());
        }
        updateWrapper.set(FirewallDO::getUpdateBy,ctx.getOperator());
        updateWrapper.eq(FirewallDO::getId,ctx.getId());
        updateWrapper.eq(FirewallDO::getStatus,beforeStateCode);
        final boolean update = firewallDaoService.update(updateWrapper);
        if (update){
            // send some event
            // 异步处理一些事
        }
        logService.saveOperationLog(ctx.getTypeEnum().getType(), ctx.getId(), event.getDescription(),"admin","操作结果："+update);
        log.info("状态机修改防火墙信息【防火墙 ID {}，修改后状态 {} ，修改结果{}】",ctx.getId(),afterStateCode,update);
    }

    public void switchAction(Integer beforeStateCode,Integer afterStateCode,CommonEvent event,CommonCtx ctx){
        LambdaUpdateWrapper<SwitchDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SwitchDO::getStatus,afterStateCode);
        if (ctx.getLaunchedTime() != null){
            updateWrapper.set(SwitchDO::getLaunchedTime,ctx.getLaunchedTime());
        }
        updateWrapper.set(SwitchDO::getUpdateBy,ctx.getOperator());
        updateWrapper.eq(SwitchDO::getId,ctx.getId());
        updateWrapper.eq(SwitchDO::getStatus,beforeStateCode);
        final boolean update = switchDaoService.update(updateWrapper);
        if (update){
            // send some event
            // 异步处理一些事
        }
        logService.saveOperationLog(ctx.getTypeEnum().getType(), ctx.getId(), event.getDescription(),"admin","操作结果："+update);
        log.info("状态机修改防火墙信息【防火墙 ID {}，修改后状态 {} ，修改结果{}】",ctx.getId(),afterStateCode,update);
    }

    public void routerAction(Integer beforeStateCode,Integer afterStateCode,CommonEvent event,CommonCtx ctx){
        LambdaUpdateWrapper<RouterDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(RouterDO::getStatus,afterStateCode);
        if (ctx.getLaunchedTime() != null){
            updateWrapper.set(RouterDO::getLaunchedTime,ctx.getLaunchedTime());
        }
        updateWrapper.set(RouterDO::getUpdateBy,ctx.getOperator());
        updateWrapper.eq(RouterDO::getId,ctx.getId());
        updateWrapper.eq(RouterDO::getStatus,beforeStateCode);
        final boolean update = routerDaoService.update(updateWrapper);
        if (update){
            // send some event
            // 异步处理一些事
        }
        logService.saveOperationLog(ctx.getTypeEnum().getType(), ctx.getId(), event.getDescription(),"admin","操作结果："+update);
        log.info("状态机修改防火墙信息【防火墙 ID {}，修改后状态 {} ，修改结果{}】",ctx.getId(),afterStateCode,update);
    }
}
